package com.haiyou.common.base;

import org.apache.ibatis.session.RowBounds;

import java.util.List;

/**
 * 通用操作数据库方法接口
 *
 * @author zhouyibin
 * @date 2019-02-28 16:36:05
 */
public interface BaseService<T> {
    /**
     * 保存一个实体，null的属性也会保存，不会使用数据库默认值
     *
     * @param t record
     * @return 返回操作结果
     */
    int insert(T t);

    /**
     * 保存一个实体，null的属性不会保存，会使用数据库默认值
     *
     * @param t record
     * @return 返回操作结果
     */
    int insertSelective(T t);

    /**
     * 批量插入，支持批量插入的数据库可以使用，例如MySQL,H2等，另外该接口限制实体包含`id`属性并且必须为自增列
     *
     * @param t record
     * @return 返回操作结果
     */
    int insertList(List<T> t);

    /**
     * 根据实体属性作为条件进行删除，查询条件使用等号
     *
     * @param t record
     * @return 返回操作结果
     */
    int delete(T t);

    /**
     * 根据Example条件删除数据
     *
     * @param o example
     * @return 返回操作结果
     */
    int deleteByExample(Object o);

    /**
     * 根据主键字段进行删除，方法参数必须包含完整的主键属性
     *
     * @param o 主键key
     * @return 返回操作结果
     */
    int deleteByPrimaryKey(Object o);

    /**
     * 根据主键更新实体全部字段，null值会被更新
     *
     * @param t record
     * @return 返回操作结果
     */
    int updateByPrimaryKey(T t);

    /**
     * 根据Example条件更新实体`record`包含的全部属性，null值会被更新
     *
     * @param t record
     * @param o example
     * @return 返回操作结果
     */
    int updateByExample(T t, Object o);

    /**
     * 根据Example条件更新实体`record`包含的不是null的属性值
     *
     * @param t record
     * @param o example
     * @return 返回操作结果
     */
    int updateByExampleSelective(T t, Object o);

    /**
     * 根据主键更新属性不为null的值
     *
     * @param t record
     * @return 返回操作结果
     */
    int updateByPrimaryKeySelective(T t);

    /**
     * 根据实体中的属性值进行查询，查询条件使用等号
     *
     * @param t record
     * @return 返回操作结果
     */
    List<T> select(T t);

    /**
     * 查询全部结果
     *
     * @return 返回列表数据
     */
    List<T> selectAll();

    /**
     * 根据Example条件进行查询
     *
     * @param o example
     * @return
     */
    List<T> selectByExample(Object o);

    /**
     * 根据example条件和RowBounds进行分页查询
     *
     * @param o         example
     * @param rowBounds rowBounds
     * @return 返回列表数据
     */
    List<T> selectByExampleAndRowBounds(Object o, RowBounds rowBounds);

    /**
     * 根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
     *
     * @param o key
     * @return 返回实体对象
     */
    T selectByPrimaryKey(Object o);

    /**
     * 根据实体属性和RowBounds进行分页查询
     *
     * @param t         record
     * @param rowBounds rowBounds
     * @return 返回列表数据
     */
    List<T> selectByRowBounds(T t, RowBounds rowBounds);

    /**
     * 根据实体中的属性查询总数，查询条件使用等号
     *
     * @param t record
     * @return 返回查询总数
     */
    int selectCount(T t);

    /**
     * 根据Example条件进行查询总数
     *
     * @param o example
     * @return 返回查询总数
     */
    int selectCountByExample(Object o);

    /**
     * 根据实体中的属性进行查询，只能有一个返回值，有多个结果是抛出异常，查询条件使用等号
     *
     * @param t record
     * @return 返回实体对象
     */
    T selectOne(T t);

    /**
     * 根据Example条件进行查询
     *
     * @param o example
     * @return 返回实体对象
     */
    T selectOneByExample(Object o);

    /**
     * 根据主键字段查询总数，方法参数必须包含完整的主键属性，查询条件使用等号
     *
     * @param o key
     * @return 返回true/false
     */
    boolean existsWithPrimaryKey(Object o);

}